import { BodySetup } from "utils/creep/CreepSetup";
import { ActionBase, ActionBaseOfCreep } from "../ActionBase";
import { PositionHelper } from "utils/position/PositionHelper";
import { EActionCode } from "framework/FSM/Action/ActionCode";


/**
 * 精确运输
 */
/*@profile*/
export class ActionAccurateTransport  extends ActionBaseOfCreep<IActionCMD<"accTransport">>
{
    // protected updateArgs(action: IActionCMD<"accTransport">): EActionCode 
    // {
    //     if(super.updateArgs(action) !== EActionCode.OK)
    //     {
    //         return EActionCode.FAILED;
    //     }
    //     const task = action.arg.entity.ownerRoom().getTaskById(action.arg.entity.getNodeMemory().taskid!,['core','creep']) as ITask<ICreepTaskData<"transportAccurate">>;
    //     if(!task)
    //     {
    //         return EActionCode.FAILED;
    //     }
    //     action.arg.task = task!.data.arg
    //     return EActionCode.OK;
    // }
    public _execute(action: IActionCMD<"accTransport">): EActionCode 
    {
        const creep = action.arg.entity;
        const taskarg = action.arg.task;
          // 精确运输任务
        if(creep.store.getUsedCapacity() == 0)
        {
            // 空了
            creep.memory.state  = 0;
        }
        else  if(creep.store.getFreeCapacity() == 0)
        {
            // 满了
            creep.memory.state  = 1;
        }
        else
        {
              // 装载了部分资源.
              /**
               * a. 当所有资源都取完了之后，即使不满也转为运输状态
               * b.
           */
            let withdrawover = true;
            const tempstore = _.cloneDeep(creep.store);
            for(const item of taskarg.List)
            {
                if(item.amount==0)
                {
                    continue;
                }
                if(tempstore[item.resourceType]!== undefined )
                {
                    if(tempstore[item.resourceType]<item.amount)
                    {
                        // 资源不足
                        withdrawover = false;

                        break;
                    }
                    else
                    {
                        // 存了部分资源
                        tempstore[item.resourceType]-=item.amount;
                    }

                }
                else
                {
                    // 资源不足
                    withdrawover = false;

                    break;
                }
            }
            if(withdrawover)
            {
                // 所有资源爬都准备好了,转为运输状态
                creep.memory.state  = 1;
                
            }
        }
        const tempcreepstore = _.cloneDeep(creep.store);
        if(!creep.memory.state)
        {
            // 取
            for(let idx=0;idx<taskarg.List.length;)
            {
                const item = taskarg.List[idx];
                const resType = item.resourceType;
                if(item.amount>0)
                {
                    if(tempcreepstore[resType] && tempcreepstore[resType] >= item.amount)
                    {
                        // 这个资源已经足够了
                        tempcreepstore[resType] -=item.amount;
                    }
                    else
                    {
                        if(PositionHelper.Distance(item.From,creep.pos)<=1)
                        {
                            const hascount =tempcreepstore[resType]?tempcreepstore[resType]:0;

                            const withdrawcount =Math.min( item.amount-hascount,creep.store.getFreeCapacity());
                            const real_withdraw = withdrawcount ;
                            // creep.log('info',`${resType}目标:${item.amount}_拿:${withdrawcount}_已有:${hascount}`);
                            const obj = Game.getObjectById(item.From.id as Id<AnyStoreStructure>);

                            if(obj)
                            {
                                const obj_count = obj.store.getUsedCapacity(resType);
                                if(!obj_count || obj_count<real_withdraw)
                                {
                                    creep.log('error',`${item.From.x}_${item.From.y}`,`[${resType}]资源[${obj_count}]小于[${real_withdraw}]`);
                                    return EActionCode.FAILED;
                                }
                                creep.withdraw(obj,resType,real_withdraw);
                                
                            }
                            else
                            {
                                creep.log('error',`找不到资源对象${item.From.id}`);
                                // 错误
                                return EActionCode.FAILED;
                            }
                        }
                        else
                        {
                            // const argmove:IMoveArg ={creepid:creep.id,pos:item.From,range:1,opt:{}} ;
                            // task.move = argmove;
                            creep.mymoveTo({pos:PositionHelper.Create(item.From),range:1},{});
                        }
                        return EActionCode.OK;
                    }
                    idx++;
                }
                else
                {
                    taskarg.List.splice( idx,1)
                }
            }
        }
        else
        {
            // 运
            let flag=true;
            for(let idx=0;idx<taskarg.List.length;)
            {
                const e = taskarg.List[idx];
                if(e.amount>0)
                {
                    if(creep.store[e.resourceType]>0)
                    {
                        flag = false;
                        if(!e.To)
                        {
                            // 异常
                            creep.log('error',`任务数据异常 没有存资源的对象数据`);
                            return EActionCode.FAILED;
                        }

                        if(PositionHelper.Distance(e.To,creep.pos)<=1)
                        {
                           
                            const obj = Game.getObjectById(e.To.id as Id<AnyStoreStructure>);
                            if(obj)
                            {
                                const storefree = obj.store.getFreeCapacity(e.resourceType);
                                const transfercount = _.min([ e.amount,creep.store.getUsedCapacity(e.resourceType),storefree]) as number;
                                if(!storefree)
                                {
                                    // 装不下了
                                    creep.log('error',`${obj.pos} 没有足够的空间`);
                                    return EActionCode.FAILED;
                                }
                                const code = creep.transfer(obj,e.resourceType,transfercount);
                                if(code == OK)
                                {
                                    e.amount -= transfercount;
                                    return EActionCode.OK;
                                }
                                else
                                {
                                    creep.log('error',`${obj.pos} 未知的错误 ${code}`);
                                    // 这里还需要仔细排查
                                    // return EActionCode.FAILED;
                                }
                            }
                            else
                            {
                                creep.log('error',`找不到资源对象${JSON.stringify(e.To)}`);
                                return EActionCode.FAILED;
                            }

                        }
                        else
                        {
                            // const argmove:IMoveArg ={creepid:creep.id,pos:e.To,range:1,opt:{}} ;
                            // arg.entity.moveTo(argmove);
                            creep.mymoveTo({pos:PositionHelper.Create(e.To),range:1},{});
                            return EActionCode.OK;
                        }
                    }
                    idx++;
                }
                else
                {
                    taskarg.List.splice( idx,1)
                }
            }
            if(flag)
            {
                creep.memory.state=0;
                
            }
        }
        if(taskarg.List.length ==0)
        {
            return EActionCode.OK;
        }
        return EActionCode.OK;
    }
}